﻿using System;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Casamiel.Application;
using Enyim.Caching;
using Microsoft.Extensions.Options;
using Casamiel.Common;
using Casamiel.Domain.Entity;
using Casamiel.Common.Extensions;
using System.Linq;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    /// Update stock command handler.
    /// </summary>
    public class UpdateStockCommandHandler:IRequestHandler<UpdateStockCommand,bool>
    {
        private readonly IStoreService _storeService;
        private readonly IProductService _product;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPre = "";
        private readonly NLog.ILogger _stocklogger = NLog.LogManager.GetLogger("StockService");
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="T:Casamiel.API.Application.Commands.UpdateStockCommandHandler"/> class.
        /// </summary>
        /// <param name="product"></param>
        /// <param name="snapshot">Snapshot.</param>
        /// <param name="storeService">Store service.</param>
        /// <param name="memcachedClient">Memcached client.</param>
        public UpdateStockCommandHandler(IProductService product, IOptionsSnapshot<CasamielSettings> snapshot, IStoreService storeService, IMemcachedClient memcachedClient)
        {
            _storeService = storeService;
            _memcachedClient = memcachedClient;
            _memcachedPre = snapshot.Value.MemcachedPre;
            _product = product;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns>The handle.</returns>
        /// <param name="request">Request.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task<bool> Handle(UpdateStockCommand request, CancellationToken cancellationToken)
        {
            try
            {
                if (request.StockPush == null || request.StockPush.productstock.Count==0)
                {
                    return true;
                }
                int count = request.StockPush.productstock.Count;

                for (int i=0; i< count;i++)
                {
                    var item = request.StockPush.productstock[i];
                    var _cacheKey = _memcachedPre + Constant.SHOPRELATIONID + item.shopid;
                    // _stocklogger.Trace($"cacheey:{_cacheKey}");
                    var storeidResult = await _memcachedClient.GetAsync<int>(_cacheKey).ConfigureAwait(false);
                    var storeId = 0;
                    if (!storeidResult.Success)
                    {
                        var entity = await _storeService.GetByRelationIdAsync<ICasaMielSession>(item.shopid).ConfigureAwait(false);
                        if (entity != null)
                        {
                            await _memcachedClient.AddAsync(_cacheKey, entity.StoreId, 72000).ConfigureAwait(false);
                            storeId = entity.StoreId;
                        }
                        else
                        {
                            await _memcachedClient.AddAsync(_cacheKey, 0, 72000).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        storeId = storeidResult.Value;
                    }
                    if (storeId > 0)
                    {
                        if(item.product!=null )
                        {
                            var p_count = item.product.Count;
                            for (int n = 0; n < p_count; n++)
                            {

                                await _product.UpdateStockAsync<ICasaMielSession>(storeId, item.product[n].pid.ToInt32(0), item.product[n].count).ConfigureAwait(false);
                                await _product.UpdateStockV2Async<ICasaMielSession>(storeId, item.product[n].pid.ToInt32(0), item.product[n].count).ConfigureAwait(false);
                                //try
                                //{
                                //    Parallel.Invoke(async () =>
                                //    {
                                //        await _product.UpdateStockAsync<ICasaMielSession>(storeId, item.product[n].pid.ToInt32(0), item.product[n].count).ConfigureAwait(false);
                                //    }, async () =>
                                //    {
                                //        await _product.UpdateStockV2Async<ICasaMielSession>(storeId, item.product[n].pid.ToInt32(0), item.product[n].count).ConfigureAwait(false);
                                //    });
                                //}
                                //catch (AggregateException ex)
                                //{
                                //    _stocklogger.Error(ex.Message);
                                //    foreach (var exinfo in ex.InnerExceptions)
                                //    {
                                //        _stocklogger.Error(exinfo.StackTrace);
                                //    }
                                //    return false;
                                //}

                            }
                        }
                         
                    }

                }
                return true;
            }
            catch (AggregateException ex)
            {
                foreach (var item in ex.InnerExceptions)
                {
                    _stocklogger.Error(item.StackTrace);
                }
                _stocklogger.Error(ex.Message);
                return false;
            }
           
        }
    }
}
